package com.zwh.se.concurrency.thread;

import java.util.concurrent.*;

/**
 * 多线程的创建，方式一：继承于Thread类
 * 方式二：实现Runnable接口创建线程
 * 方式三：实现Future接口的FutureTask类，代表异步计算的结果
 * 方式四：线程池
 */
public class Thread1Demo {
    public static void main(String[] args) throws Exception {
        //方式一
        Thread1 thread1 = new Thread1();
        thread1.start();
        //方式二
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread2 :run");
            }
        }).start();
        //方式三
        FutureTask<Integer> futureTask = new FutureTask<Integer>(new Thread3());
        new Thread(futureTask).start();
        int b = 0;
//        b = futureTask.get();//要求获得Callable线程的计算结果，如果没有计算完成就要去强求，会导致堵塞，直到计算完成
        while (!futureTask.isDone()) {//当futureTask完成后取值
            b = futureTask.get();
        }
        System.out.println(b);
        //方式四
        //- corePoolSize 线程池中的常驻核心线程数
        //创建线程池后，当有请求任务进来，就安排池中的线程去执行请求任务
        //当线程池中的线程数目达到 corePoolSize 后，就会把到达的任务放到缓存队列中
        //- maximumPoolSize
        //线程池能够容纳同时执行的最大线程数，此值必须大于等于1
        //- keepAliveTime 多余的空闲线程的存活时间
        //当前线程池数量超过 corePoolSize 时，当空闲时间达到 keepAliveTime 值时，
        //多余空闲线程会被销毁直到只剩下 corePoolSize 个线程为止
        //- unit
        //keepAliveTime 的单位
        //- workQueue
        //任务队列，被提交但尚未被执行的任务
        //- threadFactory，表示生成线程池中工作线程的线程工厂<线程名字、线程序数...>，用于创建线程一般用默认的即可
        //- handler，拒接策略，表示当队列满了并且工作线程大于等于线程池的最大线程数(maximumPoolSize)时，如何拒绝新的任务
        //JDK 内置的拒绝策略
        //AbortPolicy(默认)
        //直接抛出 RejectedExecutionException 异常阻止系统正常运行
        //CallerRunsPolicy
        //"调用者运行" 一种调节机制
        //该策略既不会抛弃任务，也不会抛出异常
        //而是将某些任务回退到调用者（由向线程池提交任务的线程来执行该任务），从而降低新任务的流量
        //DiscardOldestPolicy
        //抛弃队列中等待最久的任务
        //然后把当前任务中加入队列中尝试再次提交当前任务
        //DiscardPolicy
        //直接丢弃任务，不予任何处理也不抛出异常
        //如果允许任务丢失，这是最好的一种方案
        //以上拒绝策略都是实现了 RejectedExecutionHandler 接口
        ExecutorService threadPool = new ThreadPoolExecutor(3, 5, 1L,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy());
//                new ThreadPoolExecutor.AbortPolicy();
                //new ThreadPoolExecutor.CallerRunsPolicy();
                //new ThreadPoolExecutor.DiscardOldestPolicy();
                //new ThreadPoolExecutor.DiscardPolicy();
        try {
            for (int i = 1; i <= 10; i++) {
                threadPool.execute(() -> {
                    System.out.println(Thread.currentThread().getName() + "\t办理业务");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown();
        }
    }
}

class Thread1 extends Thread{
    @Override
    public void run() {
        System.out.println("Thread1 :run");
    }
}

class Thread3 implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("Thread3 :run");
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 1024;
    }
}